package caffeine;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.Expiry;
import com.github.benmanes.caffeine.cache.LoadingCache;
import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.nullness.qual.NonNull;

import java.util.concurrent.TimeUnit;

/**
 * @author Xiongx
 * @version 1.0
 * @date 2021/7/10 17:38
 * @since JDK 1.8
 */
public class CaffeineUtils {


    public static void main(String[] args) {
        Cache<String, Object> cache = Caffeine.newBuilder()
                .initialCapacity(100)//初始大小
                .maximumSize(200)//最大数量
                .expireAfterWrite(3, TimeUnit.SECONDS)//过期时间
                .build();




        cache.put("java金融", "java金融");
        System.out.println(cache.getIfPresent("java金融"));

        String val = (String) cache.get("java金融1", k -> getValue(k));
        System.out.println(val);


    }
    /**
     * 缓存中找不到，则会进入这个方法。一般是从数据库获取内容
     * @param k
     * @return
     */
    private static String getValue(String k) {
        return k + ":value";
    }

    //基于大小（size-based）
    public static void CacheMaxNum(){
        LoadingCache<String, String> cache = Caffeine.newBuilder()
                // 最大容量为1
                .maximumSize(1)
                .build(k->getValue(k));
        cache.put("java金融1","java金融1");
        cache.put("java金融2","java金融2");
        cache.put("java金融3","java金融3");
        cache.cleanUp();
        System.out.println(cache.getIfPresent("java金融1"));
        System.out.println(cache.getIfPresent("java金融2"));
        System.out.println(cache.getIfPresent("java金融3"));
    }

    public static void CacheTime() throws Exception{
        LoadingCache<String, String> cache =  Caffeine.newBuilder()
                // 最大容量为1
                .maximumSize(1)
                .expireAfterWrite(3, TimeUnit.SECONDS)
                .build(k->getValue(k));
        cache.put("java金融","java金融");
        Thread.sleep(1*1000);
        System.out.println(cache.getIfPresent("java金融"));
        Thread.sleep(1*1000);
        System.out.println(cache.getIfPresent("java金融"));
        Thread.sleep(1*1000);
        System.out.println(cache.getIfPresent("java金融"));
    }


    public static void CacheExpireAfterAccess() throws Exception{
        LoadingCache<String, String> cache =  Caffeine.newBuilder()
                // 最大容量为1
                .maximumSize(1)
                .expireAfterAccess(3, TimeUnit.SECONDS)
                .build(k->getValue(k));
        cache.put("java金融","java金融");
        Thread.sleep(1*1000);
        System.out.println(cache.getIfPresent("java金融"));
        Thread.sleep(1*1000);
        System.out.println(cache.getIfPresent("java金融"));
        Thread.sleep(1*1000);
        System.out.println(cache.getIfPresent("java金融"));
        Thread.sleep(3001);
        System.out.println(cache.getIfPresent("java金融"));
    }


    public static void CacheExpireAfter(){
        LoadingCache<String, String> cache = Caffeine.newBuilder()
                // 最大容量为1
                .maximumSize(1)
                .removalListener((key, value, cause) ->
                        System.out.println("key:" + key + ",value:" + value + ",删除原因:" + cause))
                .expireAfter(new Expiry<String, String>() {
                    @Override
                    public long expireAfterCreate(@NonNull String key, @NonNull String value, long currentTime) {
                        return currentTime;
                    }
                    @Override
                    public long expireAfterUpdate(@NonNull String key, @NonNull String value, long currentTime, @NonNegative long currentDuration) {
                        return currentTime;
                    }

                    @Override
                    public long expireAfterRead(@NonNull String key, @NonNull String value, long currentTime, @NonNegative long currentDuration) {
                        return currentTime;
                    }
                })
                .build(k -> getValue(k));
    }




}
